package com.hujiain.sea.register;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * OperatorFactoryBean
 *
 * @author hujiabin
 * @date 2023/11/2 20:51
 * @since 1.0
 */
public class OperatorFactoryBean implements FactoryBean<Object>, InitializingBean {
    private Class<?> type;
    private String expression;
    private Expression spelExpression;

    @Override
    public Object getObject() {
        return Proxy.newProxyInstance(type.getClassLoader(), new Class<?>[]{type}, (proxy, method, args) -> {
            EvaluationContext context = new StandardEvaluationContext();
            // rename parameters name form a
            char argName = 'a';
            for (Object arg : args) {
                context.setVariable(String.valueOf(argName++), arg);
            }
            return spelExpression.getValue(context);
        });
    }

    @Override
    public Class<?> getObjectType() {
        return type;
    }

    @Override
    public void afterPropertiesSet() {
        ExpressionParser parser = new SpelExpressionParser();
        this.spelExpression = parser.parseExpression(this.expression);
    }

    public Class<?> getType() {
        return type;
    }

    public void setType(Class<?> type) {
        this.type = type;
    }

    public String getExpression() {
        return expression;
    }

    public void setExpression(String expression) {
        this.expression = expression;
    }

}
